package holdem;

import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.Arrays;

/**
 *
 * @author qipai, Jon
 */
public abstract class IntegerCell extends ListInt {
    private String cellName;

    public static ListInt make(final Object o, final Field f) {
        try {
                String newCellName = f.getName();
                if(f.get(o) instanceof Integer) {
                    return new IntegerCell(newCellName) {

                        @Override
                        public Integer get() {
                            try {
                                return (Integer)f.get(o);
                            } catch(Exception e) {
                                e.printStackTrace();
                            }
                            return null;
                        }

                        @Override
                        public void set(Integer newValue) {
                            try {
                                f.set(o, newValue);
                            } catch(Exception e) {
                                e.printStackTrace();
                            }
                        }

                    };
                } else if(f.get(o) instanceof Boolean) {
                    return new IntegerCell(newCellName) {

                        @Override
                        public Integer get() {
                            try {
                                Boolean value = (Boolean)f.get(o);
                                if(value)
                                    return 1;
                                return 0;
                            } catch(Exception e) {
                                e.printStackTrace();
                            }
                            return null;
                        }

                        @Override
                        public void set(Integer newValue) {
                            try {
                                assert(newValue == 1 || newValue == 0) : "cannot set a boolean value other than 1 or 0";
                                Boolean b;
                                if(newValue == 1)
                                    b = true;
                                else
                                    b = false;
                                f.set(o, b);
                            } catch(Exception e) {
                                e.printStackTrace();
                            }
                        }
                    };

                } else if(f.get(o).getClass().isEnum()) {
                    return new IntegerCell(newCellName) {

                        @Override
                        public Integer get() {
                            try {
                                Enum e = (Enum)f.get(o);
                                return e.ordinal();
                            } catch(Exception e) {
                                e.printStackTrace();
                            }
                            return null;
                        }

                        @Override
                        public void set(Integer newValue) {
                            try {
                                Object[] fs = f.get(o).getClass().getEnumConstants();
                                assert(fs != null && newValue >= 0 && newValue < fs.length);
                                f.set(o, fs[newValue]);

                            } catch(Exception e) {
                                e.printStackTrace();
                            }
                        }

                    };

                } else if(f.get(o) instanceof IntegerCell) {
                    return (IntegerCell)f.get(o);
                } else { // array or etc.
                    return null;
                }
            } catch(Exception e) {e.printStackTrace();}

        return null;
    }
    public abstract Integer get();
    public abstract void set(Integer newValue);

    IntegerCell(String cellName) {
        this.cellName = cellName;
    }

    //==============
    //Implementation of ListInt Interface
    public ListInt get(Integer i) {
        return null;
    }
    public Boolean isSymbol() {
        return true;
    }
    public Boolean isList() {
        return false;
    }
    public Integer getSymbol() {
        return get();
    }
    public Integer getSize() {
        return 1;
    }

    public String getName() {
        return cellName;
    }
}
